package server;
import java.io.*;
import java.net.*;
import java.util.Iterator;

import netPacks.message;


public class clientConnection extends Thread{
		InetAddress id = null;
		Socket clientSocket = null;	
        int port = 0;
        public ObjectInputStream ois = null;
        public ObjectOutputStream oos = null;
    	message tempMsg = new message();
    	pinger pingy = new pinger(this);
    	pingChecker pingyCheck = new pingChecker(this);
    	public boolean matched = false;
    	public boolean pingerFailFlag = false;
        
        public clientConnection (Socket clientSpecific){
            clientSocket = clientSpecific;
            this.id = clientSocket.getInetAddress();
            try{
                oos = new ObjectOutputStream(clientSpecific.getOutputStream());
                oos.flush();
            	ois = new ObjectInputStream(clientSpecific.getInputStream());
            }
            catch(IOException e){
                System.err.println("Cannot open clientSpecific inputstream\n"+e.getMessage());
            }
        }
            
        public synchronized void run(){
        	while(true){
				if(!matched && !pingerFailFlag){
	        		try {
		        		System.out.println("Waiting for incoming messages...");	
						netPacks.message temp = (message) ois.readObject();
		    			msgHandler.getInstance().msgQ.add(temp);
		        	} 
					catch (IOException e) {
						System.err.println("Cannot read incoming input stream from: " + this.id+"\n"+e.getMessage());
						this.closeClient();
		                System.err.println("Client specific connection closed.");
		                if(!mainServer.getInstance().readyQ.remove(this)){
			                mainServer.getInstance().userQ.remove(this);
			                System.err.println("User removed from userQ.");
			                return;
		                }
		                System.err.println("User removed from readyQ.");
						return;
					} 
					catch (ClassNotFoundException e) {
						System.err.println("Cannot cast incoming message to correct class\n"+e.getMessage());
					}
	    			System.out.println("Added message to Queue"); //TODO: delete row
				}
				else{
					this.closeClient();
					boolean foundFlag = false;
					for(Iterator<clientConnection> it=mainServer.getInstance().userQ.iterator(); it.hasNext(); ){
						clientConnection tmp = it.next();
						if(tmp.getClientId().equals(this.getClientId())){
							it.remove();
							foundFlag = true;
							break;
						}
					}
					if(foundFlag == false){
						for(Iterator<clientConnection> it=mainServer.getInstance().readyQ.iterator(); it.hasNext(); ){
							clientConnection tmp = it.next();
							if(tmp.getClientId().equals(this.getClientId())){
								it.remove();
								break;
							}
						}
					}
					System.out.println("Removed user from queue due to connection delay.");
					break;
				}
            }
        }
               
        public InetAddress getClientId(){
        	return this.id;
        }
        public void closeClient(){
            try{
                this.oos.close();
                this.ois.close();
                this.clientSocket.close();
            }
            catch(IOException e){
                System.err.println("Cannot close client connection.\n"+e.getMessage());
            }
        }   
}
